﻿using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;

namespace BW.WMS.Redis
{
    public class RedisService : ApplicationService, IRedisService
    {
        private readonly IDistributedCache _distributedCache;

        public RedisService(IDistributedCache distributedCache)
        {
            _distributedCache = distributedCache;
        }

        /// <summary>
        /// 设置缓存
        /// </summary>
        public async Task SetAsync<T>(string key, T value, TimeSpan? expiration = null)
        {
            try
            {
                var options = new DistributedCacheEntryOptions();

                if (expiration.HasValue)
                {
                    options.SetAbsoluteExpiration(expiration.Value);
                }
                else
                {
                    options.SetAbsoluteExpiration(TimeSpan.FromHours(1));
                }

                var jsonString = JsonSerializer.Serialize(value);
                await _distributedCache.SetStringAsync(key, jsonString, options);

                Logger.LogDebug($"Redis缓存设置成功，键: {key}");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Redis缓存设置失败，键: {key}");
                throw;
            }
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        public async Task<T> GetAsync<T>(string key)
        {
            try
            {
                var jsonString = await _distributedCache.GetStringAsync(key);

                if (string.IsNullOrEmpty(jsonString))
                {
                    Logger.LogDebug($"Redis缓存未命中，键: {key}");
                    return default(T);
                }

                var result = JsonSerializer.Deserialize<T>(jsonString);
                Logger.LogDebug($"Redis缓存命中，键: {key}");
                return result;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Redis缓存获取失败，键: {key}");
                return default(T);
            }
        }

        /// <summary>
        /// 删除缓存
        /// </summary>
        public async Task RemoveAsync(string key)
        {
            try
            {
                await _distributedCache.RemoveAsync(key);
                Logger.LogDebug($"Redis缓存删除成功，键: {key}");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Redis缓存删除失败，键: {key}");
            }
        }

        /// <summary>
        /// 检查缓存是否存在
        /// </summary>
        public async Task<bool> ExistsAsync(string key)
        {
            try
            {
                var value = await _distributedCache.GetStringAsync(key);
                var exists = !string.IsNullOrEmpty(value);
                Logger.LogDebug($"Redis缓存存在检查，键: {key}，存在: {exists}");
                return exists;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Redis缓存存在检查失败，键: {key}");
                return false;
            }
        }

        /// <summary>
        /// 根据模式删除缓存键（简化实现）
        /// </summary>
        public async Task RemoveByPatternAsync(string pattern)
        {
            try
            {
                // 简化实现：记录日志，但不执行实际删除
                // 在生产环境中，可以通过维护缓存键列表来实现批量删除
                Logger.LogInformation($"请求删除缓存模式: {pattern}（简化实现，未实际删除）");
                await Task.CompletedTask;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"按模式删除缓存失败，模式: {pattern}");
            }
        }

        /// <summary>
        /// 根据模式获取缓存键列表（简化实现）
        /// </summary>
        public async Task<List<string>> GetKeysByPatternAsync(string pattern)
        {
            try
            {
                // 简化实现：返回空列表
                Logger.LogInformation($"请求获取缓存键模式: {pattern}（简化实现，返回空列表）");
                return new List<string>();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"获取匹配键列表失败，模式: {pattern}");
                return new List<string>();
            }
        }

        /// <summary>
        /// 批量删除多个缓存键
        /// </summary>
        public async Task<long> RemoveMultipleAsync(List<string> keys)
        {
            try
            {
                if (keys == null || !keys.Any())
                {
                    return 0;
                }

                long deletedCount = 0;
                foreach (var key in keys)
                {
                    try
                    {
                        await _distributedCache.RemoveAsync(key);
                        deletedCount++;
                    }
                    catch (Exception ex)
                    {
                        Logger.LogWarning(ex, $"删除缓存键失败: {key}");
                    }
                }

                Logger.LogInformation($"批量删除缓存完成，成功删除: {deletedCount}/{keys.Count}");
                return deletedCount;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"批量删除缓存失败，键数量: {keys?.Count ?? 0}");
                return 0;
            }
        }
    }
}